/**
* @program: src
*
* @description:
*
* @author: Mr.chen
*
* @create: 2022-04-13 16:59
**/
package auth

import (
	"context"
	"time"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
)

const defaultExpiration = 5 * time.Minute

// An Authenticator is used to authenticate the rpc requests.
type Authenticator struct {
	key    string
	token string
}

// NewAuthenticator returns an Authenticator.
func NewAuthenticator(key string, token string) (*Authenticator, error) {
	return &Authenticator{
		key:    key,
		token: token,
	}, nil
}

// Authenticate authenticates the given ctx.
func (a *Authenticator) Authenticate(ctx context.Context) error {
	md, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return status.Error(codes.Unauthenticated, missingMetadata)
	}

	apps, tokens := md[appKey], md[tokenKey]
	if len(apps) == 0 || len(tokens) == 0 {
		return status.Error(codes.Unauthenticated, missingMetadata)
	}

	app, token := apps[0], tokens[0]
	if len(app) == 0 || len(token) == 0 {
		return status.Error(codes.Unauthenticated, missingMetadata)
	}

	return a.validate(app, token)
}

func (a *Authenticator) validate(app, token string) error {
	if app!=a.key ||  token != a.token {
		return status.Error(codes.Unauthenticated, accessDenied)
	}
	return nil
}
